﻿#region Declaration

//------------------------------------------------------------------------------
// Compas Information Techonoly Co., Ltd
// The Initial Developer of the Original Code is CompasSolutions.
// All Rights Reserved.
// 
// Contributor(s): _______. 
//------------------------------------------------------------------------------

#endregion

#region Using Directives

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Configuration;

#endregion

namespace QuickDev.Common.Security
{
    // Use of this class requires an AppSetting in web.config:
    //<appSettings>
    //	<add key="TamperProofKey" value="YourUglyRandomKeyLike-lkj54923c478" />
    //</appSettings>
    //Wannafly.Security.TamperProofString.QueryStringDecode(Request.QueryString("Data"))
    //Wannafly.Security.TamperProofString.QueryStringEncode(InputData.Text)
    public class TamperProofString
    {
        //Function to encode the string
        static public string TamperProofStringEncode( string value , string key )
        {
            System.Security.Cryptography.MACTripleDES mac3des = new System.Security.Cryptography.MACTripleDES();
            System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            mac3des.Key = md5.ComputeHash( System.Text.Encoding.UTF8.GetBytes( key ) );
            return System.Convert.ToBase64String( System.Text.Encoding.UTF8.GetBytes( value ) ) + System.Convert.ToChar( "-" ) + System.Convert.ToBase64String( mac3des.ComputeHash( System.Text.Encoding.UTF8.GetBytes( value ) ) );
        }

        //Function to decode the string
        //Throws an exception if the data is corrupt
        static public string TamperProofStringDecode( string value , string key )
        {
            String dataValue = String.Empty;
            String calcHash = String.Empty;
            String storedHash = String.Empty;

            System.Security.Cryptography.MACTripleDES mac3des = new System.Security.Cryptography.MACTripleDES();
            System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            mac3des.Key = md5.ComputeHash( System.Text.Encoding.UTF8.GetBytes( key ) );

            try
            {
                dataValue = System.Text.Encoding.UTF8.GetString( System.Convert.FromBase64String( value.Split( System.Convert.ToChar( "-" ) )[0] ) );
                storedHash = System.Text.Encoding.UTF8.GetString( System.Convert.FromBase64String( value.Split( System.Convert.ToChar( "-" ) )[1] ) );
                calcHash = System.Text.Encoding.UTF8.GetString( mac3des.ComputeHash( System.Text.Encoding.UTF8.GetBytes( dataValue ) ) );

                if ( storedHash != calcHash )
                {
                    //Data was corrupted
                    throw new ArgumentException( "Hash value does not match" );
                    //This error is immediately caught below
                }

            }
            catch ( System.Exception )
            {
                throw new ArgumentException( "Invalid TamperProofString" );
            }
            return dataValue;
        }

        static public string QueryStringEncode( string value )
        {
            return HttpContext.Current.Server.UrlEncode( TamperProofStringEncode( value , ConfigurationManager.AppSettings["TamperProofKey"] ) );
        }

        static public string QueryStringDecode( string value )
        {
            return TamperProofStringDecode( value , ConfigurationManager.AppSettings["TamperProofKey"] );
        }
    }
}